#include "fileutils.h"

FileUtils::FileUtils()
{
}


QStringList FileUtils::getDirList(QString path)
{
    QDir dir(path);
    if (!dir.exists()) {
        return QStringList();
    }
    dir.setFilter(QDir::Dirs);
    // dir.setFilter(QDir::Dirs|QDir::Files);
    QStringList list = dir.entryList();
    list.removeOne(".");
    list.removeOne("..");
    return list;
}


QStringList FileUtils::getFileList(QString path)
{
    QDir dir(path);
    if (!dir.exists()) {
        return QStringList();
    }
    dir.setFilter(QDir::Files);
    QStringList list = dir.entryList();
    return list;
}


QString FileUtils::readFileToString(QString fileName)
{
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
        QMessageBox::warning(nullptr, "Warning", "Cannot open file: " + file.errorString());
        return nullptr;
    }
    QTextStream in(&file);
    in.setCodec("UTF-8");
    QString text = in.readAll();
    file.close();
    return text;
}

void FileUtils::writeStringToFile(QString fileName, QString data)
{
    QFile file(fileName);
    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        QMessageBox::warning(nullptr, "Warning", "Cannot save file: " + file.errorString());
        return;
    }
    QTextStream out(&file);
    out.setCodec("UTF-8");
    out << data;
    out.flush();
    file.close();
}

bool FileUtils::mkdirs(const QString &dirPath)
{
    QDir dir(dirPath);

    if (dir.exists())
        return false;
    bool rel = dir.mkpath(".");
    if (!rel)
        qDebug() << "Failed to create directory path: " << dirPath;

    return rel;
}

bool FileUtils::createNewFile(const QString &fileName)
{
    bool rel = false;
    QFile file(fileName);
    if (!file.exists()) {
        // 文件不存在
        rel = file.open(QIODevice::WriteOnly);
        if (!rel) {
            qDebug() << "Failed to create file.";
        }
    }
    file.close();

    return rel;
}

QString FileUtils::GetCorrectUnicode(const QByteArray &ba) {
    QTextCodec::ConverterState state;
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QString text = codec->toUnicode(ba.constData(), ba.size(), &state);
    if (state.invalidChars > 0) {
        text = QTextCodec::codecForName("GBK")->toUnicode(ba);
    } else {
        //text = ba;
    }
    return text;
}

QString FileUtils::getFileString(QString fileName) {
    QFile f(fileName);
    QFileInfo fileInfo(fileName);
    if (!(f.exists() && fileInfo.isFile())) {
        qDebug() << "文件不存在";
        return nullptr;
    }
    if (!f.open(QIODevice::ReadWrite | QIODevice::Text)) {
        qDebug() << "文件打开失败";
        return nullptr;
    }
    QByteArray textAll = f.readAll();
    f.close();
    QString text = GetCorrectUnicode(textAll);
    return text;
}

QString detectEncoding(const QString &filePath) {
    QTextCodec::ConverterState state;
//    QTextCodec *codec;
//    QByteArray data;

    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        return QString(); // 返回空字符串表示错误
    }

    QByteArray data = file.read(1024); // 读取前1024个字节
    file.close();

    // 检查 BOM
    if (data.startsWith("\xEF\xBB\xBF")) { // UTF-8 BOM
        return "UTF-8";
    } else if (data.startsWith("\xFE\xFF")) { // UTF-16 BE BOM
        return "UTF-16BE";
    } else if (data.startsWith("\xFF\xFE")) { // UTF-16 LE BOM
        return "UTF-16LE";
    } // 可以添加更多 BOM 检查

    // 尝试其他编码（例如 GBK, GB18030）
    QTextCodec *codec = QTextCodec::codecForName("GBK"); // 尝试 GBK
    QString decoded = codec->toUnicode(data.constData(), data.size(), &state);
    if (state.invalidChars == 0) { // !decoded.contains('\xFFFD') // \xFFFD 表示解码错误字符
        return "GBK"; // 假设 GBK 成功
    }

    // 如果需要，可以添加更多编码检查和逻辑

    return QString(); // 如果无法确定，返回空字符串
}


// 假设 detectFileEncoding 函数用于检测文件编码
QString detectFileEncoding(const QString &filePath) {
    // 实现文件编码检测的方法，可以使用前述的 detectEncoding 函数
    // 替换为你选择的编码检测方法
    // 返回检测到的文件编码，或空字符串表示未检测到或检测失败
    // ...（在这里实现检测文件编码的代码）...

    QTextCodec::ConverterState state;
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        return QString(); // 返回空字符串表示错误
    }

    QByteArray data = file.read(1024); // 读取前1024个字节
    file.close();

    // 检查 BOM
    if (data.startsWith("\xEF\xBB\xBF")) { // UTF-8 BOM
        return "UTF-8";
    } else if (data.startsWith("\xFE\xFF")) { // UTF-16 BE BOM
        return "UTF-16BE";
    } else if (data.startsWith("\xFF\xFE")) { // UTF-16 LE BOM
        return "UTF-16LE";
    } // 可以添加更多 BOM 检查

    // 尝试其他编码（例如 GBK, GB18030）
    QTextCodec::codecForName("UTF-8")->toUnicode(data.constData(), data.size(), &state);
    if (state.invalidChars == 0) {
        return "UTF-8";
    }
    QTextCodec::codecForName("GBK")->toUnicode(data.constData(), data.size(), &state);
    if (state.invalidChars == 0) {
        return "GBK";
    }
    return QString(); // 这里暂时返回空字符串，需要实现文件编码检测的方法
}

QStringList FileUtils::readFileByLine(const QString &filePath) {
    QStringList dataList;

    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Failed to open file for reading.";
        return QStringList();
    }

    QString encoding = detectFileEncoding(filePath);

    // 使用检测到的编码打开文件并读取内容
    QTextStream in(&file);
    if (!encoding.isEmpty()) {
        QTextCodec *codec = QTextCodec::codecForName(encoding.toUtf8());
        if (codec) {
            in.setCodec(codec);
        } else {
            qDebug() << "Failed to set codec for encoding:" << encoding;
            file.close();
            return QStringList();
        }
    }

    while (!in.atEnd()) {
        QString line = in.readLine();
        dataList.append(line);
    }

    file.close();
    return dataList;
}
